Frolian's blog

xkcd, Python, math and beyond

Fun with the Samsung ringtone

There's this ringtone. Everyone has it. Especially here, in Korea. It's a whistling. A really cool whistling sound. And you know what? I'm bored so we're gonna have some fun with this tune!

In [1]:
%matplotlib inline
from pylab import *
In [4]:
from scipy.io import wavfile
In [72]:
sample_freq, whistle = wavfile.read("files/samsung_ringtone.wav")

For those that haven't heard this thing, you can hear it below:

In [75]:
from IPython.display import Audio
Audio(data = whistle[:, 0], rate=sample_freq)
Out[75]:

Visualizing the waveform

What does this ringtone look like if we plot its waveform?

In [77]:
t = arange(whistle.shape[0], dtype=float32) / sample_freq
subplot(211)
plot(t, whistle[:, 0])
xlabel("time (s)")
title('left channel')
grid(True)
subplot(212)
plot(t, whistle[:, 1])
xlabel("time (s)")
title('right channel')
grid(True)
tight_layout()

As one can see, the plot clearly shows the 5 tones that are whistled. A first question one can ask himself is "why do the two signals look alike so much? is there a difference between the two?". Luckily, we can plot the difference:

Visualizing the echo

In [78]:
plot(t, whistle[:, 1] - whistle[:, 0])
xlabel("time (s)")
grid(True)
title("Difference between left and right")
Out[78]:
<matplotlib.text.Text at 0xa61ba30>

Mmmh, that's intriguing. When we listen to that, what do we hear?

In [80]:
Audio(whistle[:, 1] - whistle[:, 0], rate=sample_freq)
Out[80]:

It's not pretty, but it seems to me that this is some sort of echo. In what follows, we will just work with one sound, a mix of the previous two ones!

In [81]:
new_whistle = mean(whistle, axis=1)
In [82]:
Audio(new_whistle, rate=sample_freq)
Out[82]:

Visualizing the spectrogram

When you listen closely to that sound, you can hear that the 4th note is a sort of sliding tone. Can we plot a spectrogram and actually show this?

In [83]:
specgram(new_whistle, Fs=sample_freq)
xlim(0, 1.1)
ylim(0, 10000)
xlabel('time (s)')
ylabel('frequency (Hz)')
Out[83]:
<matplotlib.text.Text at 0xa85efd0>

Indeed, we can see that the fourth sound is not very horizontal, but rather sloped upwards: I would say it's a slide from a note to another.

Fun with ringtones and permutations

Until now everything we did was fun. But what do you do when you're in Korea and everyone use the original ringtone with his phone? You surely would like to stand out and be original, right?

Below, we'll develop a recipe for being original: first we segment the ringtone in its components and then we recreate all the possible permuations of the ringtone with these components. So that in the end, it sounds just like the real thing, but different. Let's get started!

Below, we plot the times at which the ringtone is split into chunks.

In [86]:
chunk_times = [0., 0.22, 0.38, 0.5, 0.92, 1.2]

specgram(new_whistle, Fs=sample_freq)
xlim(0, 1.1)
ylim(0, 10000)
xlabel('time (s)')
ylabel('frequency (Hz)')

for time in chunk_times[:-1]:
    vlines(time, 0, 10000)
In [88]:
from scipy.signal import get_window

chunks = []
for start, end in zip(chunk_times[:-1], chunk_times[1:]):
    chunks.append(new_whistle[(t > start) & (t < end)] * get_window('hamming', t[(t > start) & (t < end)].size))
In [89]:
for chunk in chunks:
    display(Audio(chunk, rate=44100))

Now that we have the individual chunks, we can permute all of them and rebuild the new ones!

In [90]:
from itertools import permutations

for p in permutations((0, 1, 2, 3, 4)):
    out = []
    for elem in p:
        if len(out) == 0:
            out = chunks[elem].copy() 
        else:
            out = concatenate((out, chunks[elem].copy()))
    display(Audio(out, rate=44100))

So what do you say now? You can use one of the unique \(5! - 1 = 119\) other ringtones that were sitting hidden in the original ringtone and set it as your phone alert sound. Isn't that nice? :)

Sound Music

Comments